package locadora.dados;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;



import locadora.negocio.pessoas.Pessoa;
import miscelanea.Data;

public class RepositorioPessoa implements Repositorio{
	
	//nome do arquivo de Pessoas
	final String NOME_ARQUIVO = "pessoas.bin";
	private ObjectInputStream entrada = null;
	private ObjectOutputStream saida = null;
	//Lista de objetos a serem escritos ou de onde foram recuperados os itens.
	ArrayList<Pessoa> arrayPessoa = null;
	
	/**
	 * Repositorio de Pessoas
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public RepositorioPessoa() throws FileNotFoundException, IOException, ClassNotFoundException{
		//inicia uma lista vazia
		this.arrayPessoa = new ArrayList<Pessoa>();
		//busca todos os elementos constantes no arquivo
		this.recupera();
	}
	
	/**
	 * Retorna uma representação da lista de Pessoas em formato String
	 * @return
	 */
	public String toString(){
		String resultado = "";
		for(Pessoa pessoa: arrayPessoa)
			resultado += pessoa;
		return resultado;
		
	}
	
	@Override
	public void armazena() throws IOException{
		File file = new File(this.NOME_ARQUIVO);
		//Deleta o arquivo, se ele existir
		file.delete();
		this.saida = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(this.NOME_ARQUIVO)));
		//Escreve o array no arquivo de saída e fecha
		saida.writeObject(this.arrayPessoa);
		saida.close();
	}
	
	@SuppressWarnings("unchecked")
	/**
	 * Busca todos os objetos guardados em disco
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	private void recupera() throws IOException, ClassNotFoundException{
		File file = new File(this.NOME_ARQUIVO);
		//Se o arquivo não existia e acabou de ser criado
		if(file.createNewFile()){
			//Escreve uma lista de Pessoas vazia no arquivo de saída e o fecha
			this.saida = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(this.NOME_ARQUIVO)));
			this.saida.writeObject(this.arrayPessoa);
			this.saida.close();
		}else{
			//Abre o arquivo para leitura
			FileInputStream fileInputStream = new FileInputStream(NOME_ARQUIVO);
			BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
			//Se houver ao menos um byte a ser lido do arquivo de entrada, assume que lá existe o objeto ArrayList de Pessoas
			if(bufferedInputStream.available() > 0){
				//Recupera o ArrayList e fecha o arquivo de entrada
				this.entrada = new ObjectInputStream(bufferedInputStream);
				this.arrayPessoa = (ArrayList<Pessoa>) entrada.readObject();
				fileInputStream.close();
				bufferedInputStream.close();
				entrada.close();
			}
		}
	}
	
	/**
	 * Quando este repositório é coletado pelo garbage collector ou quando a VM se encerra, armazena todos os dados em disco
	 */
	protected void finalize() throws IOException{
		this.armazena();
	}

	@Override
	public Pessoa busca(String chave) throws Exception{
		recupera();
		for(Pessoa pessoa : this.arrayPessoa)
			if(pessoa.getChave().equals(chave))
				return pessoa;
		return null;
	}
	
	@Override
	public void adiciona(Object objeto) throws Exception{
		this.arrayPessoa.add((Pessoa)objeto);
		armazena();
	}
	
	@Override
	public ArrayList<Object> ListarObjetos() {
		ArrayList<Object> arrayObject = new ArrayList<Object>();
		for(Pessoa pessoa : arrayPessoa){
			arrayObject.add(pessoa);
		}
		return arrayObject;
	}
	
	@Override
	public void remove(String chave){
		for(int i = 0; i < this.arrayPessoa.size(); i++)
			if(this.arrayPessoa.get(i).getChave() == chave)
				this.arrayPessoa.remove(i);
	}
	
	
	public static void main(String[] args){
		
		try {
			
			RepositorioPessoa repositorio = new RepositorioPessoa();
			
			Pessoa i1 = new Pessoa("Anderson", new Data("13021986"), "6334563", "SSPPE", "22233366638", null, "51790550", null, null, null);
			Pessoa i2 = new Pessoa("Victor", new Data("13021986"), "6334563", "SSPPE", "22233366638", null, "51790550", null, null, null);
			Pessoa i3 = new Pessoa("Renno", new Data("13021986"), "6334563", "SSPPE", "22233366638", null, "51790550", null, null, null);
			Pessoa i4 = new Pessoa("Eduardo", new Data("13021986"), "6334563", "SSPPE", "22233366638", null, "51790550", null, null, null);
			
			System.out.println("Array antes das inserções(vazio):\n\n" + repositorio);
			repositorio.adiciona(i1);
			repositorio.adiciona(i2);
			repositorio.adiciona(i3);
			repositorio.adiciona(i4);
			System.out.println("Array após as inserções:(1,2,3,4)\n\n" + repositorio);
			repositorio.armazena();
			System.out.println("Array após armazenamento(1,2,3,4):\n\n" + repositorio);
			repositorio.recupera();
			System.out.println("Array após recuperação(1,2,3,4):\n\n" + repositorio);
			repositorio.adiciona(i1);
			System.out.println("Array após inserção(1,2,3,4,1):\n\n" + repositorio);
			repositorio.armazena();
			System.out.println("Array após armazenamento(1,2,3,4,1):\n\n" + repositorio);
			repositorio.recupera();
			System.out.println("Array após recuperação(1,2,3,4,1):\n\n" + repositorio);
			
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (ClassNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
